/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package com.evangelion.core.controller;

import com.evangelion.core.FacturaProveedor;
import com.evangelion.core.bean.Cliente;
import com.evangelion.core.bean.Proveedor;
import com.evangelion.core.bean.Seccione;
import com.evangelion.core.bean.Usuario;
import com.evangelion.core.service.FacturaProveedorService;
import com.evangelion.core.service.ProveedorService;
import com.evangelion.core.serviceImpl.FacturaProveedorServiceImpl;
import com.evangelion.core.serviceImpl.ProveedorServiceImpl;
import com.evangelion.core.daoImpl.ConnectionUtil;
import com.evangelion.core.utils.MensajesFace;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.InputStream;
import java.io.Serializable;
import java.sql.Connection;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import javax.annotation.PostConstruct;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ViewScoped;
import javax.faces.context.FacesContext;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import net.sf.jasperreports.engine.JasperExportManager;
import net.sf.jasperreports.engine.JasperFillManager;
import net.sf.jasperreports.engine.JasperPrint;
import net.sf.jasperreports.engine.JasperReport;
import net.sf.jasperreports.engine.util.JRLoader;
import org.primefaces.model.DefaultStreamedContent;

/**
 *
 * @author Kellycasma
 */
@ManagedBean
@ViewScoped
public class ProveedorController extends MensajesFace implements Serializable {

    private Proveedor proveedor;
    ProveedorService psi = new ProveedorServiceImpl();
    String valorBusqueda;
    List<Proveedor> listaProveedor;
    List<Proveedor> listProveedorSelect;
    Usuario usu;
    Seccione seccio;
    FacturaProveedor facturaProveedor;
    FacturaProveedorService facturaProveedorService = new FacturaProveedorServiceImpl();
    List<FacturaProveedor> listaFacturaProv;
    List<FacturaProveedor> listaFacturaProv2;
    Date fechadesde;
    Date fechahasta;
    Date fechaI;
    Date fechaf;
    String valorBusquedaFactura;
    String searchProveedor;
    boolean renderTableproveedor;
    DefaultStreamedContent dc;

    @PostConstruct
    public void init() {
        proveedor = new Proveedor();
        facturaProveedor = new FacturaProveedor();
        proveedor.setCliente(new Cliente());
        proveedor.setSeccion(new Seccione());
        listaProveedor = new ArrayList<Proveedor>();
        listaFacturaProv = new ArrayList<FacturaProveedor>();
        listaFacturaProv2 = new ArrayList<FacturaProveedor>();

        FacesContext context = FacesContext.getCurrentInstance();
        HttpServletRequest request = (HttpServletRequest) context.getExternalContext().getRequest();
        HttpSession httpSession = request.getSession(false);
        if (httpSession != null) {
            usu = (Usuario) httpSession.getAttribute("UserSession");
            seccio = (Seccione) httpSession.getAttribute("seccion");
        }
        listaProveedor = psi.searchByCifNombre(seccio, "");
    }

    public void save() {
        if (validarForm()) {
            proveedor.setCliente(usu.getCliente());
            proveedor.setSeccion(seccio);

            psi.save(proveedor);
            limpiarForm();
            msgCambiosGuardados();
            init();
        }
    }

    public void saveFacturaProveedor() {
        facturaProveedor.setCliente(usu.getCliente());
        facturaProveedor.setSeccion(seccio);
        facturaProveedorService.save(facturaProveedor);
        msgCambiosGuardados();
        init();
    }

    public void limpiarForm() {
        proveedor = new Proveedor();
    }

    public boolean validarForm() {
        boolean requerido = true;
        if (!isCifValido(proveedor.getCif())) {
            msgValidacion("EL CIF");
            requerido = false;
        }
        try {
            Proveedor proveedorTemporal = psi.findObjByParam("cif", proveedor.getCif());
            if (proveedorTemporal != null) {
                if ((proveedor.getId() == null || (!proveedor.getId().equals(proveedorTemporal.getId()) && proveedor.getId() != null))) {
                    msgValidacion("Ya existe este CIF pertenece a " + proveedorTemporal.getNombres());
                    requerido = false;
                } else {
                    if (proveedor.getId() != null) {
                        proveedor.setCif(proveedorTemporal.getCif());
                    }
                }
            }
        } catch (Exception ex) {
            msgValidacion("Ha ocurrido un error");
            return false;
        }
        return requerido;
    }

    public void printpdf(Map parameters, String archivo, String name) {
        try {
            Connection conexion = ConnectionUtil.getConnection();
            String urlMaster = ConnectionUtil.getServletContext().getRealPath(File.separator + "general" + File.separator + "reportes" + File.separator + archivo);
            JasperReport reporteMaster = null;
            try {
                reporteMaster = (JasperReport) JRLoader.loadObject(urlMaster);
            } catch (Exception e) {
                e.printStackTrace();
            }
            JasperPrint print = null;
            print = JasperFillManager.fillReport(reporteMaster, parameters, conexion);
            byte[] bytes = JasperExportManager.exportReportToPdf(print);
            System.out.println("byte: " + bytes.length);
            if (bytes.length >= 1211 && bytes.length <= 1608) {
                System.out.println("tamano menor");
                dc = null;
                msgValidacion("El reporte no genero ningun resultado");
            } else {
                InputStream stream = new ByteArrayInputStream(bytes);
                dc = new DefaultStreamedContent(stream, "application/pdf", name+".pdf");
                System.out.println("Reporte generado exitosamente.");
            }
            ConnectionUtil.closeConect();
        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }

    public void prueba(String cif, Date fI, Date fF) {
        if (!isCifValido(cif)) {
            msgValidacion("EL CIF");
        } else {
            String archivo = "reporteProveedor.jasper";
            Map parameters = new HashMap();
            parameters.put("cif", cif);
            parameters.put("fechaI", fI);
            parameters.put("fechaF", fF);
            printpdf(parameters, archivo, "infProveedor_"+cif);
        }

    }

    public void provxLote() {
        String archivo = "reporteProveedorLote.jasper";
        Map parameters = new HashMap();
        parameters.put("fechaI", fechaI);
        parameters.put("fechaF", fechaf);
        printpdf(parameters, archivo,"infProveedores");

    }

    public void search() {
        System.out.println("...valorBusqueda" + valorBusqueda);
        listaProveedor = psi.searchByCifNombre(seccio, valorBusqueda);
    }

    public void searchFacturaProveedor() {
        listaFacturaProv = facturaProveedorService.findByFecha(seccio, fechadesde, fechahasta, valorBusquedaFactura);
    }

    public void searchFacturaProveedor2() {
        listaFacturaProv2 = facturaProveedorService.findByFecha(seccio, fechaI, fechaf, "");
        System.out.println("listaFacturaProv2:"+listaFacturaProv2.size());
        provxLote();
    }

    public void buscarListaProveedor() {
        listProveedorSelect = psi.searchByCifNombre(seccio, searchProveedor);
        renderTableproveedor = true;
    }

    public void onRowSelectProveedor(Proveedor provee) {
        renderTableproveedor = false;
        facturaProveedor.setProveedor(provee);
        searchProveedor = provee.getNombres();
    }

    public static boolean isCifValido(String cif) {

        boolean resultado = false;

        try {
            String vCif = cif.trim();

            int suma = 0;
            int contador = 0;
            int temporal = 0;
            int codigoControl = 0;
            String cadenaTemporal = null;
            String valoresCif = "ABCDEFGHJKLMNPQRSUVW";
            String letraControlCIF = "0123456789";
            String letraSociedadNumerica = "KLMNPQRSW";
            String primeraLetra = null;
            String ultimaLetra = null;

            // Comprueba la longitud correcta del CIF.
            if (!(vCif.length() == 9)) {
                return false;
            }

            // Si encuentra alg�n caracter que no sea una letra o un n�mero, el cif
            // no es valido.
            if (vCif.matches("[^A-Za-z0-9]")) {
                return false;
            }

            // Convierte a may�sculas la cadena.
            vCif = vCif.toUpperCase();

            // Obtiene la primera letra (letra de la sociedad) y la �ltima letra del
            // CIF (letra de control).
            primeraLetra = vCif.substring(0, 1);

            // Obtiene la �ltima letra del CIF, para comprobar si es v�lida.
            ultimaLetra = vCif.substring(8, 9);

            // Comprueba si la primera letra es v�lida.
            if (valoresCif.indexOf(primeraLetra) < 0) {
                return false;
            }

            // Obtiene el c�digo de control.
            // Sumamos las cifras pares
            suma = suma + Integer.parseInt(vCif.substring(2, 3)) + Integer.parseInt(vCif.substring(4, 5))
                    + Integer.parseInt(vCif.substring(6, 7));

            // Ahora cada cifra impar la multiplicamos por dos y sumamos las cifras
            // del resultado.
            for (contador = 1; contador < 8; contador = contador + 2) {
                // Multiplica por 2
                temporal = (Integer.parseInt(vCif.substring(contador, contador + 1)) * 2);

                // Suma los digitos.
                // Diferencia si tiene una cifra, por ejemplo: 8 = 8
                // o si tiene varias, por ejemplo: 16 -> 6 + 1 = 7
                if (temporal < 10) {
                    suma = suma + temporal;
                } else {
                    cadenaTemporal = String.valueOf(temporal);
                    suma = suma + (Integer.parseInt(cadenaTemporal.substring(0, 1)))
                            + (Integer.parseInt(cadenaTemporal.substring(1, 2)));
                }
            }

            // Obtiene las unidades de la suma y se las resta a 10, para obtener el
            // d�gito de control.
            codigoControl = ((10 - (suma % 10)) % 10);

            // Si la letra es K, L, M, N, P, Q � S entonces al codigo de control le
            // suma 64 y
            // obtengo su ASCII para ver si coincide con la ultima letra del cif.
            if (letraSociedadNumerica.indexOf(primeraLetra) >= 0) {
                byte[] ascii = new byte[1];

                // Obtiene el c�digo ASCII asociado, al sumar 64 al c�digo de
                // control.
                if (codigoControl == 0) {
                    codigoControl = 10;
                }
                codigoControl = codigoControl + 64;
                ascii[0] = (Integer.valueOf(codigoControl)).byteValue();

                // El �ltimo d�gito tiene que coincidir con el d�gito de control
                // obtenido
                resultado = (ultimaLetra.equals(new String(ascii)));
            } else {
                // Para el resto de letras de comienzo de CIF el �ltimo d�gito debe ser
                // num�rico,
                // y coincidir con el c�digo de control.
                resultado = (codigoControl == letraControlCIF.indexOf(ultimaLetra));
            }
        } catch (Exception e) {
            // Si ha habido alg�n error es porque hay alg�n parseo que tira bien.
            resultado = false;
        }
        return resultado;
    }

    public Proveedor getProveedor() {
        return proveedor;
    }

    public void setProveedor(Proveedor proveedor) {
        this.proveedor = proveedor;
    }

    public String getValorBusqueda() {
        return valorBusqueda;
    }

    public void setValorBusqueda(String valorBusqueda) {
        this.valorBusqueda = valorBusqueda;
    }

    public List<Proveedor> getListaProveedor() {
        return listaProveedor;
    }

    public void setListaProveedor(List<Proveedor> listaProveedor) {
        this.listaProveedor = listaProveedor;
    }

    public FacturaProveedor getFacturaProveedor() {
        return facturaProveedor;
    }

    public void setFacturaProveedor(FacturaProveedor facturaProveedor) {
        this.facturaProveedor = facturaProveedor;
    }

    public List<FacturaProveedor> getListaFacturaProv() {
        return listaFacturaProv;
    }

    public void setListaFacturaProv(List<FacturaProveedor> listaFacturaProv) {
        this.listaFacturaProv = listaFacturaProv;
    }

    public Date getFechadesde() {
        return fechadesde;
    }

    public void setFechadesde(Date fechadesde) {
        this.fechadesde = fechadesde;
    }

    public Date getFechahasta() {
        return fechahasta;
    }

    public void setFechahasta(Date fechahasta) {
        this.fechahasta = fechahasta;
    }

    public String getValorBusquedaFactura() {
        return valorBusquedaFactura;
    }

    public void setValorBusquedaFactura(String valorBusquedaFactura) {
        this.valorBusquedaFactura = valorBusquedaFactura;
    }

    public String getSearchProveedor() {
        return searchProveedor;
    }

    public void setSearchProveedor(String searchProveedor) {
        this.searchProveedor = searchProveedor;
    }

    public boolean isRenderTableproveedor() {
        return renderTableproveedor;
    }

    public void setRenderTableproveedor(boolean renderTableproveedor) {
        this.renderTableproveedor = renderTableproveedor;
    }

    public List<Proveedor> getListProveedorSelect() {
        return listProveedorSelect;
    }

    public void setListProveedorSelect(List<Proveedor> listProveedorSelect) {
        this.listProveedorSelect = listProveedorSelect;
    }

    public DefaultStreamedContent getDc() {
        return dc;
    }

    public void setDc(DefaultStreamedContent dc) {
        this.dc = dc;
    }

    public Date getFechaI() {
        return fechaI;
    }

    public void setFechaI(Date fechaI) {
        this.fechaI = fechaI;
    }

    public Date getFechaf() {
        return fechaf;
    }

    public void setFechaf(Date fechaf) {
        this.fechaf = fechaf;
    }

    public List<FacturaProveedor> getListaFacturaProv2() {
        return listaFacturaProv2;
    }

    public void setListaFacturaProv2(List<FacturaProveedor> listaFacturaProv2) {
        this.listaFacturaProv2 = listaFacturaProv2;
    }
}
